package com.liu.jbase.service.mongo.impl;

import java.io.Serializable;
import java.util.Calendar;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.mapreduce.GroupBy;
import org.springframework.data.mongodb.core.mapreduce.GroupByResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import com.liu.jbase.PageListVo;
import com.liu.jbase.service.mongo.IMongoClient;
import com.liu.tools.LogUtil;

/**
 * @date 2017年5月13日
 * @time 下午5:25:43
 * @author liuxingmi
 * @desc  插入数据
 * @param <T>
 */
public class MongoClientImpl<T> implements IMongoClient<T> {

	private static Logger logger = Logger.getLogger(MongoClientImpl.class);

	@Autowired
	private MongoTemplate mongoTemplate;

	@Override
	public void insert(T entity) throws Exception {
		try {
			mongoTemplate.insert(entity);
		} catch (Exception e) {
			logger.error(LogUtil.msg("MongoApiImpl:insert", "插入数据异常"), e);
			throw new Exception();
		}
	}
	
	public void update(T entity) throws Exception {
		try {
			mongoTemplate.save(entity);
		} catch (Exception e) {
			logger.error(LogUtil.msg("MongoApiImpl:update", "修改数据异常"), e);
			throw new Exception();
		}
	}

	public void updateById(Serializable id, String key, String value, Class<T> entity) throws Exception {
		try {
			mongoTemplate.updateFirst(new Query(Criteria.where("id").is(id)), new Update().set("updateTime", Calendar.getInstance().getTime()).set(key, value), entity);
		} catch (Exception e) {
			logger.error(LogUtil.msg("MongoApiImpl:updateById", "修改数据异常"), e);
			throw new Exception();
		}
	}

	public void update(Query query, String key, String value, Class<T> entity) throws Exception {
		try {
			mongoTemplate.updateFirst(query, new Update().set("updateTime", Calendar.getInstance().getTime()).set(key, value), entity);
		} catch (Exception e) {
			
			logger.error(LogUtil.msg("MongoApiImpl:update", "修改数据异常"), e);
			throw new Exception();
		}
	}

	public void update(Query query, Update update, Class<T> entity) throws Exception {
		try {
			mongoTemplate.updateFirst(query, update, entity);
		} catch (Exception e) {
			
			logger.error(LogUtil.msg("MongoApiImpl:update", "修改数据异常"), e);
			throw new Exception();
		}
	}

	public void deleteById(Serializable id, Class<T> entity) throws Exception {
		try {
			mongoTemplate.remove(new Query(Criteria.where("id").is(id)), entity);
		} catch (Exception e) {
			
			logger.error(LogUtil.msg("MongoApiImpl:deleteById", "删除数据异常"), e);
			throw new Exception();
		}
	}

	public void deleteByQuery(Query query, Class<T> entity) throws Exception {
		try {
			mongoTemplate.remove(query, entity);
		} catch (Exception e) {
			
			logger.error(LogUtil.msg("MongoApiImpl:deleteByQuery", "删除数据异常"), e);
			throw new Exception();
		}
	}

	public T getOneById(Serializable id, Class<T> entity) throws Exception {
		T obj = null;
		try {
			obj = mongoTemplate.findOne(new Query(Criteria.where("id").is(id)), entity);
		} catch (Exception e) {
			
			logger.error(LogUtil.msg("MongoApiImpl:getOneById", "查询数据异常"), e);
			throw new Exception();
		}
			
		
		return obj;
	}

	public T getOne(Query query, Class<T> entity) throws Exception {
		T obj = null;
		try {
			obj = mongoTemplate.findOne(query, entity);
		} catch (Exception e) {
			
			logger.error(LogUtil.msg("MongoApiImpl:getOne", "查询数据异常"), e);
			throw new Exception();
		}
		return obj;
	}

	public List<T> getAll(Class<T> entity) throws Exception {
		List<T> list = null;
		try {
			list = mongoTemplate.findAll(entity);
		} catch (Exception e) {
			
			logger.error(LogUtil.msg("MongoApiImpl:getAll", "查询数据异常"), e);
			throw new Exception();
		}
		return list;
	}

	public List<T> getAll(Query query, Class<T> entity) throws Exception {
		List<T> list = null;
		try {
			list = mongoTemplate.find(query, entity);
		} catch (Exception e) {
			
			logger.error(LogUtil.msg("MongoApiImpl:getAll", "查询数据异常"), e);
			throw new Exception();
		}
		return list;
	}

	public long getCount(Query query, Class<T> entity) throws Exception {
		long count = 0;
		try {
			count = mongoTemplate.count(query, entity);
		} catch (Exception e) {
			
			logger.error(LogUtil.msg("MongoApiImpl:getCount", "查询数据异常"), e);
			throw new Exception();
		}
		return count;
	}

	public PageListVo<T> getPage(Query query, PageListVo<T> page, Class<T> entity) throws Exception {
		PageListVo<T> pageListVo = null;
		try {

			Long total = this.getCount(query, entity);
			int currPage = page.getCurrPage();
			int pageSize = page.getPageSize();
			if(query == null){
				query = new Query();
			}
			query.skip((currPage - 1) * pageSize).limit(pageSize);
			List<T> pageList = this.mongoTemplate.find(query, entity);
			pageListVo = new PageListVo<T>(total, pageList, currPage, pageSize);
			
		} catch (Exception e) {
			
			logger.error(LogUtil.msg("MongoApiImpl:getPage", "分页数据异常"), e);
			throw new Exception();
		}
		return pageListVo;
	}

	@Override
	public GroupByResults<T> group(Criteria criteria, String inputCollectionName, GroupBy groupBy, Class<T> entity) throws Exception {
		
		GroupByResults<T> groupByResults = null;
		
		try {
			groupByResults = mongoTemplate.group(criteria, inputCollectionName, groupBy, entity);
		} catch (Exception e) {
			
			logger.error(LogUtil.msg("MongoApiImpl:group", "统计数据异常"), e);
			throw new Exception();
		}
		
		return groupByResults;
	}

	@Override
	public T findAndUpdate(Query query, Update update, Class<T> entity) throws Exception {
		
		try {
			
			return mongoTemplate.findAndModify(query, update, entity);
		} catch (Exception e) {
			logger.info("查询并修改数据异常 query"+query);
			logger.info("查询并修改数据异常 update"+update);
			logger.info("查询并修改数据异常 entity"+entity);
			logger.info("查询并修改数据异常,异常信息为"+ e.getMessage());
		}
		return null;
		
	}

}
